<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/26
 * Time: 9:17
 */

namespace app\index\controller;
use think\Db;

use think\Controller;

class Export extends Controller
{
    /*
     * https://blog.csdn.net/Drug_/article/details/78716358 EXCEL大数据导出限制很多 用CSV更好更灵活
     */
    public function index(){
        $this->putCsv(['AAAA','BBB']);
    }

    public function putCsv($head, $mark = 'attack_ip_info', $fileName = "test.csv")
    {

        set_time_limit(0);
        $sqlCount = Db::table('sun_order')->count();
        //输出Excel文件头，可把user.csv换成你要的文件名
        header('Content-Type: application/vnd.ms-excel;charset=utf-8');
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Cache-Control: max-age=0');
        $sqlLimit = 100000;//每次只从数据库取100000条以防变量缓存太大
        //每隔$limit行，刷新一下输出buffer，不要太大，也不要太小
        $limit = 100000;
        //buffer计数器
        $cnt = 0;
        $fileNameArr = array();
        //逐行取出数据，不浪费内存
        for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {
            $fp = fopen($mark . '_' . $i . '.csv', 'w'); //生成临时文件
            //chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限
            $fileNameArr[] = $mark . '_' . $i . '.csv';
            //将数据通过fputcsv写到文件句柄
            fputcsv($fp, $head);
            $dataArr = Db::table('sun_order')->limit($i * $sqlLimit, $sqlLimit)->select();
            foreach ($dataArr as $a) {
                $cnt++;
                if ($limit == $cnt) {
                    //刷新一下输出buffer，防止由于数据过多造成问题
                    ob_flush();
                    flush();
                    $cnt = 0;
                }
                fputcsv($fp, $a);
            }
            fclose($fp);//每生成一个文件关闭
        }

//        //进行多个文件压缩
//        $zip = new ZipArchive();
//        $filename = $mark . ".zip";
//        $zip->open($filename, ZipArchive::CREATE);//打开压缩包
//        foreach ($fileNameArr as $file) {
//            $zip->addFile($file, basename($file));//向压缩包中添加文件
//        }
//        $zip->close();//关闭压缩包
//        foreach ($fileNameArr as $file) {
//            unlink($file);//删除csv临时文件
//        }
//        //输出压缩文件提供下载
//        header("Cache-Control: max-age=0");
//        header("Content-Description: File Transfer");
//        header('Content-disposition: attachment; filename=' . basename($filename));
//        header("Content-Type: application/zip");
//        header("Content-Transfer-Encoding: binary");
//        header('Content-Length: ' . filesize($filename));
//        @readfile($filename);//输出文件;
//        unlink($filename); //删除压缩包临时文件
    }

    public function csv()
    {

        //https://blog.csdn.net/sun124608666/article/details/83182764
        //php导出超过10万行数据到excel ok
//        发现记事本打开中文正常,但是excel打开中文乱码;
//        原因是　通过查看编码发现，导出的 CSV 程序文件是 UTF-8 无BOM编码格式，而我们通常使用 UTF-8 编码格式 都是有 BOM 的。吧执行导出的代码改为有bom编码,再次导出好了
        $file_name = '业绩查询表';
        set_time_limit(0);
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="'.$file_name.'.csv"');
        header('Cache-Control: max-age=0');

        $counts = Db::name('order')->count();//总数
        $limit = ceil($counts / 1000);//分页数
        // 打开PHP文件句柄，php://output 表示直接输出到浏览器
        $fp = fopen('php://output', 'a');
        $head = array('刘志艳', 'sno', 'num', 'name', 'text', 'img', 'small_img');
        foreach ($head as $i => $v) {
            // CSV的Excel支持GBK编码，一定要转换，否则乱码
            //$head[$i] = iconv("utf-8", "gb2312//IGNORE", $v);

        }
        fputcsv($fp, $head);
        $i = 1;
        $n = 1;
        while ($n <= $limit) {
            //每次取出固定条数 然后在循环写入,写入一条$i+1;循环完毕$n+1 $n小于$limit 如果执行条数大于20000相当于执行20页数据 清空缓存区
            $items = Db::name('order')->limit(($n - 1) * 1000, 1000)->select();
            foreach ($items as $key => $val) {
                fputcsv($fp, $val);
                $i++;
            }
            if ($i > 20000) { //读取一部分数据刷新下输出buffer
                ob_flush();
                flush();
                $i = 0;
            }
            $n++;
            /*
            if($n == 300){
            break;
            }
            */

        }

    }

    public function read()
    {

        set_time_limit(0);
        $file = fopen('./111.csv', 'r');
        while ($data = fgetcsv($file)) {    //每次读取CSV里面的一行内容
            //print_r($data); //此为一个数组，要获得每一个数据，访问数组下标即可
            $goods_list[] = $data;
            dump($data);
        }
        echo $goods_list[0][1];
        fclose($file);
    }

    public function input_csv($filename,$field,$table) {
        //https://blog.csdn.net/sun124608666/article/details/83182764
        //$field 打散为数组
        $fieldArr = explode(',', $field);
        //CSV转数组 $excelData
        $content = trim(file_get_contents($filename));
        $excelData = explode("\n",$content); //把字符串打散为数组
        //删除第一行标题
        array_splice($excelData, 0, 1);

        // 将这个大量数据（10W+）的数组分割成5000一个的小数组。这样就一次批量插入5000条数据。mysql 是支持的。
        $chunkData = array_chunk($excelData ,5000);
        $count = count($chunkData);
        for ($i = 0; $i < $count; $i++) {
            $insertRows = array();
            foreach($chunkData[$i] as $value){
                //转码，有中文不要用这种方式，会出乱码
                //$string = mb_convert_encoding(trim(strip_tags($value)), 'utf-8', 'gbk');
                $string = trim(strip_tags($value));//转码
                $v = explode(',', $string); //把字符串打散为数组
                $row = array();
                for($j=0;$j<count($fieldArr);$j++){
                    $row[$fieldArr[$j]] = $v[$j];
                }
                $sqlString = "('".implode( "','", $row )."')"; //把数组元素组合为字符串 批量
                $insertRows[] = $sqlString;
            }
            $result = $this->addData($table,$insertRows,$field); //批量将sql插入数据库。
        }
        return $result;
    }


}